#import "SRTrackingTableView.h"
#import "NSCell+SRAdditions.h"
#import "RNConstants.h"

@implementation SRTrackingTableView

@synthesize trackingRow = trackingRow_;
@synthesize trackingCell = trackingCell_;

-(id)initWithFrame:(NSRect)frame {
    if (!(self = [super initWithFrame:frame]))
        return nil;
    
    [self setTrackingRow:-1];
    return self;
}

-(id)initWithCoder:(NSCoder *)coder {
    if (!(self = [super initWithCoder:coder]))
        return nil;
    
    [self setTrackingRow:-1];
    return self;
}

- (BOOL)acceptsFirstResponder {
    return NO;
}

-(void)updateTrackingAreas {
    for (NSTrackingArea *area in [self trackingAreas])
        [self removeTrackingArea:area];
    
    NSPoint mouseLocation = [self convertPoint:[[self window] convertScreenToBase:[NSEvent mouseLocation]] fromView:nil];
    NSRange visibleRows = [self rowsInRect:[self visibleRect]];
    for (NSUInteger row = visibleRows.location; row < NSMaxRange(visibleRows); row++ ) {
        NSCell *visibleCell = [self preparedCellAtColumn:0 row:row];
        if (![visibleCell respondsToSelector:@selector(addTrackingAreasForView:inRect:withUserInfo:mouseLocation:)]) 
            continue;
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:row] forKey:RNRowKey];
        [visibleCell addTrackingAreasForView:self inRect:[self frameOfCellAtColumn:0 row:row] withUserInfo:userInfo mouseLocation:mouseLocation];
    }
}

- (void)mouseEntered:(NSEvent *)event {
    NSDictionary *userInfo = [event userData];
    NSNumber *row = [userInfo valueForKey:RNRowKey];
    if (!row) 
        return;
    NSInteger rowValue = [row integerValue]; 
    NSCell *cell = [self preparedCellAtColumn:0 row:rowValue];
    [self setTrackingRow:rowValue];
    [self setTrackingCell:[cell copy]];
    [[self trackingCell] setControlView:self];
    [[self trackingCell] mouseEntered:event];
}

- (void)mouseExited:(NSEvent *)event {
    NSDictionary *userInfo = [event userData];
    NSNumber *row = [userInfo valueForKey:RNRowKey];
    if (!row) 
        return;
    NSCell *cell = [self preparedCellAtColumn:0 row:[row integerValue]];
    [cell mouseExited:event];
    [self setTrackingCell:nil];
    [self setTrackingRow:-1];
}

- (NSCell *)preparedCellAtColumn:(NSInteger)column row:(NSInteger)row {
    if ([self selectedCell] == nil && row == [self trackingRow]) {
        // TODO: THIS IS A BIT OF A HACK TO UPDATE THE TRACKING CELL - CAN THIS BE GENERALIZED?
//        id object = [[self itemAtRow:[self trackingRow]] representedObject];
//        id data = [object valueForKeyPath:@"objectDictionary"];
//        [[self trackingCell] setObjectValue:data];
        return [self trackingCell];
    }
    return [super preparedCellAtColumn:column row:row];
}

- (void)updateCell:(NSCell *)aCell {
    if (aCell == [self trackingCell]) {
        [self setNeedsDisplayInRect:[self frameOfCellAtColumn:0 row:[self trackingRow]]];
    }
    [super updateCell:aCell];
}

- (void)highlightSelectionInClipRect:(NSRect)clipRect {
    // No-op.  Highlighting is done in the custom cells
}

- (BOOL)inLiveResize {
    return NO;
}

@end
